home *** CD-ROM | disk | FTP | other *** search
- /*
- * file.c
- *
- * Copyright 2000, Silicon Graphics, Inc.
- * ALL RIGHTS RESERVED
- *
- * UNPUBLISHED -- Rights reserved under the copyright laws of the United
- * States. Use of a copyright notice is precautionary only and does not
- * imply publication or disclosure.
- *
- * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
- * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
- * in similar or successor clauses in the FAR, or the DOD or NASA FAR
- * Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
- * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
- *
- * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
- * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
- * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
- * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
- * GRAPHICS, INC.
- */
- /* $XConsortium: file.c /main/cde1_maint/1 1995/07/17 16:42:36 drk $ */
- /*****************************************************************************
- *****************************************************************************
- **
- ** File: file.c
- **
- ** Description: File transfer functions for the CDE Drag & Drop Demo.
- **
- ** (c) Copyright 1993, 1994 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994 International Business Machines Corp.
- ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
- ** Novell, Inc.
- **
- ****************************************************************************
- ************************************<+>*************************************/
-
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/param.h>
-
- #include <X11/Intrinsic.h>
-
- #include <Xm/Xm.h>
- #include <Xm/DrawingA.h>
- #include <Xm/Frame.h>
- #include <Xm/Protocols.h>
-
- #include <Dt/Dt.h>
- #include <Dt/Dnd.h>
-
- #include "icon.h"
- #include "demo.h"
- #include "file.h"
-
- extern Widget topLevel;
- extern XtAppContext appContext;
-
- /*************************************************************************
- *
- * Data Structures & Private Declarations For Appointment Buffers
- *
- **************************************************************************/
-
- /*
- * Specification of drag or drop directory
- */
-
- typedef enum {
- DragDirectory,
- DropDirectory
- } DragOrDrop;
-
- /*
- * File names and contents. The contents are the minimal required by the
- * data typing service to correctly type the file via content-based typing.
- * The file names are appropriate to the type of the contents as well. This
- * demo uses content-based typing to get the appropriate icons for these files.
- */
-
- #define FILE_NAME_CSH "runit"
- #define FILE_DATA_CSH "#! /bin/csh"
-
- #define FILE_NAME_PS "map.ps"
- #define FILE_DATA_PS "%!PS-Adobe-2.0"
-
- #define FILE_NAME_TEXT "tasks"
- #define FILE_DATA_TEXT "Nothing"
-
- /*
- * Private file function declarations
- */
-
- static XtActionProc fileCheckForDragProc(Widget, XEvent*, String*,
- Cardinal*);
- static void fileConvertCallback(Widget, XtPointer, XtPointer);
- static void fileCreateDirectory(char*);
- static void fileCreateFile(char*, char*, char*);
- static void fileCreateFiles(Widget);
- static void fileDragStart(Widget, XEvent*, IconInfo*, int);
- static char* fileGetContents(char*);
- static char* fileGetDemoDirectory();
- static char* fileGetDirectoryName(DragOrDrop);
- static void fileRemoveDirectory(char*);
- static void fileShutdown(Widget, XtPointer, XtPointer);
-
- /*************************************************************************
- *
- * File Name Drag & Drop
- *
- **************************************************************************/
-
- /*
- * fileConvertCallback
- *
- * When converting the data, fills in the file structure with the name(s) of
- * the file(s). When converting DELETE, removes the given file(s) and icon(s)
- * from the filesystem and drawing area respectively.
- */
- static void
- fileConvertCallback(
- Widget dragContext,
- XtPointer clientData,
- XtPointer callData)
- {
- DtDndConvertCallbackStruct *convertInfo =
- (DtDndConvertCallbackStruct *) callData;
- IconInfo *iconArray = (IconInfo *) clientData;
- char filePath[MAXPATHLEN + 1],
- command[MAXPATHLEN + 4];
- int ii;
- Widget fileDraw;
-
- if (convertInfo == NULL) {
- return;
- }
-
- /*
- * Verify the protocol and callback reason
- */
-
- if (convertInfo->dragData->protocol != DtDND_FILENAME_TRANSFER ||
- (convertInfo->reason != DtCR_DND_CONVERT_DATA &&
- convertInfo->reason != DtCR_DND_CONVERT_DELETE)) {
- return;
- }
-
- switch (convertInfo->reason) {
- case DtCR_DND_CONVERT_DATA:
-
- /*
- * Supply the file names of the dragged files
- */
-
- for (ii = 0; ii < convertInfo->dragData->numItems; ii++) {
- sprintf(filePath, "%s/%s",
- fileGetDirectoryName(DragDirectory),
- iconArray[ii].name);
- convertInfo->dragData->data.files[ii] =
- XtNewString(filePath);
- }
- break;
- case DtCR_DND_CONVERT_DELETE:
-
- /*
- * Delete dragged files as second part of a move operation
- */
-
- fileDraw = XtNameToWidget(topLevel, "*fileDraw");
-
- for (ii = 0; ii < convertInfo->dragData->numItems; ii++) {
-
- /* Remove file(s) */
-
- sprintf(filePath, "%s/%s",
- fileGetDirectoryName(DragDirectory),
- iconArray[ii].name);
- sprintf(command, "rm %s", filePath);
- if (system(command) != 0) {
- printf("Unable to remove file \"%s\".\n",
- filePath);
- }
-
- /* Remove icon(s) */
-
- if (fileDraw != NULL) {
- IconDelete(fileDraw, &iconArray[ii]);
-
- XClearWindow(XtDisplayOfObject(fileDraw),
- (XtWindow(fileDraw)));
- XtCallCallbacks(fileDraw, XmNexposeCallback,
- NULL);
- }
- }
- break;
- }
- }
-
- /*
- * fileDragFinishCallback
- *
- * Free the file names allocated in fileConvertCallback()
- */
- void
- fileDragFinishCallback(
- Widget widget,
- XtPointer clientData,
- XtPointer callData)
- {
- DtDndDragFinishCallbackStruct *dragFinishInfo =
- (DtDndDragFinishCallbackStruct *)callData;
- DtDndContext *dragData = dragFinishInfo->dragData;
- int ii;
-
- for (ii = 0; ii < dragData->numItems; ii++) {
- XtFree(dragData->data.files[ii]);
- }
- }
-
- /*
- * fileTransferCallback
- *
- * Handles the transfer of a file or appointment to the draw area.
- * Adds the appropriate icon to the list of icons on the draw area.
- */
- void
- fileTransferCallback(
- Widget widget,
- XtPointer clientData,
- XtPointer callData)
- {
- DtDndTransferCallbackStruct *transferInfo =
- (DtDndTransferCallbackStruct *) callData;
- IconInfo *iconList = NULL, *iconPtr;
- char *filePath, *name, *contents,
- command[2*MAXPATHLEN + 5];
- int ii;
-
- if (transferInfo == NULL) {
- return;
- }
-
- /*
- * Verify the protocol and callback reasons
- */
-
- if (transferInfo->dropData->protocol != DtDND_FILENAME_TRANSFER ||
- transferInfo->reason != DtCR_DND_TRANSFER_DATA) {
- return;
- }
-
- if (widget != NULL) {
- XtVaGetValues(widget, XmNuserData, &iconList, NULL);
- }
-
- /*
- * Copy the dropped file(s) to the drop directory
- */
-
- for (ii = 0; ii < transferInfo->dropData->numItems; ii++) {
-
- /* Copy the file(s) */
-
- filePath = transferInfo->dropData->data.files[ii];
-
- contents = fileGetContents(filePath);
-
- if ((name = strrchr(filePath,'/')) == NULL) {
- name = filePath;
- } else {
- name++;
- }
- sprintf(command, "cp %s %s", filePath,
- fileGetDirectoryName(DropDirectory));
- if (system(command) != 0) {
- printf("Could not copy file \"%s\" to \"%s\".\n",
- filePath, fileGetDirectoryName(DropDirectory));
- transferInfo->status = DtDND_FAILURE;
- return;
- }
-
- /* Create icon(s) for new file(s) at the drop site */
-
- iconPtr = IconNew();
- IconInitialize(widget, iconPtr,
- transferInfo->x + ii * 10,
- transferInfo->y + ii * 10,
- contents, strlen(contents), name, IconByData);
- iconPtr->next = iconList;
- if (iconList != NULL) {
- iconList->prev = iconPtr;
- }
- iconList = iconPtr;
- XtVaSetValues(widget, XmNuserData, iconList, NULL);
- XtFree(contents);
- }
- }
-
- /*
- * fileDragSetup
- *
- * Prepares the file draw area to be a drag source.
- */
- void
- fileDragSetup(
- Widget fileDraw)
- {
- char translations[] = "<Btn2Down>: fileCheckForDragProc()";
- XtTranslations newTranslations;
- XtActionsRec actionTable[] = {
- {"fileCheckForDragProc", (XtActionProc)fileCheckForDragProc},
- };
-
- XtAppAddActions(appContext, actionTable, 1);
- newTranslations = XtParseTranslationTable(translations);
- XtVaSetValues(fileDraw, XmNtranslations, newTranslations, NULL);
-
- XtAddEventHandler(fileDraw, Button1MotionMask, False,
- (XtEventHandler)demoDragMotionHandler,
- (XtPointer)DtDND_FILENAME_TRANSFER);
-
- fileCreateFiles(fileDraw);
- }
-
- /*
- * fileDropSetup
- *
- * Such a function is not needed since the demoDropSetup() in demo.c registers
- * the draw area as a drop site for drops of file names.
- */
-
- /*
- * fileDragStart
- *
- * Initiates a file drag. The function fileCheckForDrag() first determines
- * if the pointer is over a file icon before calling this function.
- */
- static void
- fileDragStart(
- Widget widget,
- XEvent *event,
- IconInfo *iconArray,
- int numFiles)
- {
- static XtCallbackRec convertCBRec[] = { {fileConvertCallback, NULL},
- {NULL, NULL} };
- static XtCallbackRec dragFinishCBRec[] =
- { {demoDragFinishCallback, NULL},
- {fileDragFinishCallback, NULL},
- {NULL, NULL} };
- Widget dragIcon;
- Arg arg[1];
-
- convertCBRec[0].closure = (XtPointer) iconArray;
-
- /*
- * Set up drag icon
- */
-
- if (numFiles == 1) {
- if (iconArray[0].dragIcon == NULL) {
- iconArray[0].dragIcon = DtDndCreateSourceIcon(widget,
- iconArray[0].bitmap, iconArray[0].mask);
- }
- dragIcon = iconArray[0].dragIcon;
- } else {
- dragIcon = NULL; /* Use default multiple provided by library */
- }
-
- XtSetArg(arg[0], DtNsourceIcon, (XtArgVal)dragIcon);
-
- /*
- * Start the drag
- */
-
- if (DtDndDragStart(widget, event, DtDND_FILENAME_TRANSFER, numFiles,
- XmDROP_COPY | XmDROP_MOVE,
- convertCBRec, dragFinishCBRec, arg, 1)
- == NULL) {
-
- printf("DragStart returned NULL.\n");
- }
- }
-
- /*
- * fileCheckForDragProc
- *
- * Called when button 2 is pressed in the file drag area. Calls
- * fileCheckForDrag() to determine if the button was pressed over a file
- * icon in which case a drag is started.
- */
- static XtActionProc
- fileCheckForDragProc(
- Widget widget,
- XEvent *event,
- String *params,
- Cardinal *numParams)
- {
- fileCheckForDrag(widget, event, event->xbutton.x, event->xbutton.y);
- }
-
- /*
- * fileCheckForDrag
- *
- * Determine if the pointer is over a file icon (within the drag threshold)
- * when button 2 is pressed or when button 1 was pressed and the drag
- * threshold has been exceeded.
- */
- void
- fileCheckForDrag(
- Widget widget,
- XEvent *event,
- int initialX,
- int initialY)
- {
- IconInfo *iconList, *iconPtr, *iconArray;
-
- XtVaGetValues(widget, XmNuserData, &iconList, NULL);
-
- if (iconList == NULL) {
- printf("Unable to locate icon list.\n");
- }
-
- for (iconPtr = iconList; iconPtr != NULL; iconPtr = iconPtr->next) {
- if ((initialX > (int)iconPtr->icon.x &&
- initialX < (int)(iconPtr->icon.x + iconPtr->icon.width)) &&
- (initialY > (int)iconPtr->icon.y &&
- initialY < (int)(iconPtr->icon.y + iconPtr->icon.height))){
-
- /*
- * This starts a single file drag. To start a multiple
- * file drag add elements to the icon array here. The
- * convert and transfer callbacks are already written
- * to handle multiple file transfers.
- */
-
- iconArray = (IconInfo *)XtCalloc(1,sizeof(IconInfo));
- iconArray[0] = *iconPtr;
-
- fileDragStart(widget, event, iconArray, 1);
- }
- }
- }
-
- /*************************************************************************
- *
- * File Creation, Initialization & Destruction
- *
- *************************************************************************/
-
- /*
- * fileCreateDragSource
- *
- * Create draw area with a frame to serve as the drag source for files.
- */
- Widget
- fileCreateDragSource(
- Widget parent)
- {
- Widget fileFrame,
- fileDraw;
-
- fileFrame = XtVaCreateManagedWidget("fileFrame",
- xmFrameWidgetClass, parent,
- NULL);
-
- fileDraw = XtVaCreateManagedWidget("fileDraw",
- xmDrawingAreaWidgetClass, fileFrame,
- NULL);
- XtAddCallback(fileDraw, XmNexposeCallback, demoDrawExposeCallback,NULL);
-
- return fileDraw;
- }
-
- /*
- * fileCreateDropSite
- *
- * Such a function is not needed since the drop site is the draw area which
- * is created in demoCreateDropSite() in demo.c
- */
-
- /*
- * fileCreateDirectory
- *
- * Create the given directory.
- */
- static void
- fileCreateDirectory(
- char *directory)
- {
- char command[MAXPATHLEN + 8];
-
- sprintf(command, "mkdir %s", directory);
- if (system(command) != 0) {
- printf("Unable to create directory \"%s\"\n", directory);
- exit(1);
- }
- }
-
- /*
- * fileCreateFile
- *
- * Given a path (partial or absolute), a file name and data create a file
- * containing the given data using the given path.
- */
- static void
- fileCreateFile(
- char *filePath,
- char *fileName,
- char *fileData)
- {
- FILE *fp;
- char filePathAndName[MAXPATHLEN];
-
- sprintf(filePathAndName, "%s/%s", filePath, fileName);
-
- if ((fp = fopen(filePathAndName, "w")) == NULL) {
- printf("Cannot create file \"%s\" in current directory.\n"
- "Exiting...\n", filePathAndName);
- exit(1);
- }
- if (fwrite(fileData, strlen(fileData), 1, fp) != 1) {
- printf("Cannot write file \"%s\" in current directory.\n"
- "Exiting...\n", filePathAndName);
- exit(1);
- }
- fclose(fp);
- }
-
- /*
- * fileCreateFiles
- *
- * Create drag and drop directories and the files to drag.
- */
- static void
- fileCreateFiles(
- Widget fileDraw)
- {
- IconInfo *iconList,
- *iconPtr;
- char *dragDirectory,
- *dropDirectory;
- Atom WM_DELETE_WINDOW;
-
- WM_DELETE_WINDOW = XmInternAtom(XtDisplay(topLevel), "WM_DELETE_WINDOW",
- False);
- XmAddWMProtocolCallback(topLevel, WM_DELETE_WINDOW, fileShutdown,
- (XtPointer)NULL);
-
- dragDirectory = fileGetDirectoryName(DragDirectory);
- dropDirectory = fileGetDirectoryName(DropDirectory);
-
- fileRemoveDirectory(dragDirectory);
- fileCreateDirectory(dragDirectory);
-
- fileRemoveDirectory(dropDirectory);
- fileCreateDirectory(dropDirectory);
-
- fileCreateFile(dragDirectory, FILE_NAME_TEXT, FILE_DATA_TEXT);
- fileCreateFile(dragDirectory, FILE_NAME_CSH, FILE_DATA_CSH);
- fileCreateFile(dragDirectory, FILE_NAME_PS, FILE_DATA_PS);
-
- iconPtr = IconNew();
- IconInitialize(fileDraw, iconPtr, 40, 25,
- FILE_DATA_TEXT, strlen(FILE_DATA_TEXT),
- FILE_NAME_TEXT, IconByData);
-
- iconList = iconPtr;
- iconPtr = IconNew();
- iconPtr->next = iconList;
- iconList->prev = iconPtr;
-
- IconInitialize(fileDraw, iconPtr, 105, 25,
- FILE_DATA_CSH, strlen(FILE_DATA_CSH),
- FILE_NAME_CSH, IconByData);
-
- iconList = iconPtr;
- iconPtr = IconNew();
- iconPtr->next = iconList;
- iconList->prev = iconPtr;
-
- IconInitialize(fileDraw, iconPtr, 75, 95,
- FILE_DATA_PS, strlen(FILE_DATA_PS),
- FILE_NAME_PS, IconByData);
-
- iconList = iconPtr;
-
- XtVaSetValues(fileDraw, XmNuserData, iconList, NULL);
- }
-
- /*
- * fileRemoveDirectory
- *
- * Remove the given directory and its contents if the directory exists.
- */
- static void
- fileRemoveDirectory(
- char *directory)
- {
- struct stat fileStatus;
- char command[MAXPATHLEN + 8];
-
- if (stat(directory, &fileStatus) == 0) { /* directory exists */
- sprintf(command, "rm -rf %s", directory);
- if (system(command) != 0) {
- printf("Unable to remove directory \"%s\"\n"
- "Please remove this directory by hand "
- "and try again.\n", directory);
- exit(1);
- }
- }
- }
-
- /*
- * fileShutdown
- *
- * Remove the temporary file
- */
- static void
- fileShutdown(
- Widget widget,
- XtPointer clientData,
- XtPointer callData)
- {
- fileRemoveDirectory(fileGetDirectoryName(DragDirectory));
- fileRemoveDirectory(fileGetDirectoryName(DropDirectory));
- }
-
- /*************************************************************************
- *
- * File Utility Functions
- *
- *************************************************************************/
-
- /*
- * fileGetContents
- *
- * Open the specified file and read the contents into a buffer which is
- * returned.
- */
- static char*
- fileGetContents(
- char *filePath)
- {
- char *contents = NULL;
- struct stat fileStatus;
- FILE *fp;
-
- if (stat(filePath, &fileStatus) == 0) { /* file exists */
- contents = (char *) XtMalloc(fileStatus.st_size + 1);
- if ((fp = fopen(filePath, "r")) == NULL) {
- printf("Cannot open file \"%s\" for reading.\n",
- filePath);
- XtFree(contents);
- contents = NULL;
- } else if (fread(contents, fileStatus.st_size, 1, fp) != 1) {
- printf("Cannot read file \"%s\".\n", filePath);
- XtFree(contents);
- contents = NULL;
- }
- if (contents != NULL) {
- contents[fileStatus.st_size] = NULL;
- }
- fclose(fp);
- }
- return contents;
- }
-
- /*
- * fileGetDemoDirectory
- *
- * Return the directory where the demo directories reside.
- */
- static char*
- fileGetDemoDirectory()
- {
- static char *demoDirectory = NULL;
- char currentDirectory[MAXPATHLEN];
- int status;
-
- if (demoDirectory == NULL) {
- demoDirectory = (char *) getenv("DNDDEMODIR");
- if (demoDirectory == NULL) {
- demoDirectory = (char *) getcwd(NULL, MAXPATHLEN);
- if (demoDirectory == NULL) {
- sprintf(
- "getcwd() could not get current directory.\n"
- "\tUsing \".\" instead.\n",
- NULL);
- demoDirectory = ".";
- } else {
- /* strip off the /tmp_mnt */
- if (strncmp(demoDirectory, "/tmp_mnt/", 9) == 0) {
- demoDirectory += 8;
- }
- }
- }
- }
- return demoDirectory;
- }
-
- /*
- * fileGetDirectoryName
- *
- * Gets the name of the directory where the files are dragged from or dropped
- * to depending on which is requested.
- */
- static char*
- fileGetDirectoryName(
- DragOrDrop dragOrDrop)
- {
- static char *dragDirectory = NULL;
- static char *dropDirectory = NULL;
-
- switch (dragOrDrop) {
- case DragDirectory:
- if (dragDirectory == NULL) {
- dragDirectory = (char *) XtMalloc(MAXPATHLEN + 1);
- sprintf(dragDirectory, "%s/FileDragDir",
- fileGetDemoDirectory());
- }
- return dragDirectory;
- break;
- case DropDirectory:
- if (dropDirectory == NULL) {
- dropDirectory = (char *) XtMalloc(MAXPATHLEN + 1);
- sprintf(dropDirectory, "%s/FileDropDir",
- fileGetDemoDirectory());
- }
- return dropDirectory;
- break;
- default:
- return NULL;
- }
- }
-
- /*
- * fileStoreBuffer
- *
- * Store a buffer into a file in the drop directory.
- * A temporary file may be created if required.
- */
- char *
- fileStoreBuffer(
- char *name,
- void *buf,
- int len)
- {
- char path[MAXPATHLEN];
- char *dir = fileGetDirectoryName(DropDirectory);
- struct stat statInfo;
- FILE *fp;
-
- if (name == NULL)
- name = "unnamed";
-
- sprintf(path, "%s/%s", dir, name);
-
- if (stat(path, &statInfo) == 0) {
- char *tPath;
-
- if ((tPath = tempnam(dir, name)) == NULL)
- return (char *)NULL;
- strcpy(path, tPath);
- free(tPath);
- }
-
- if ((fp = fopen(path, "w")) == NULL) {
- printf("Cannot create file \"%s\"\n", path);
- return (char *)NULL;
- }
-
- if (fwrite(buf, len, 1, fp) != 1) {
- printf("Cannot write to file \"%s\".\n", path);
- return (char *)NULL;
- }
-
- fclose(fp);
-
- return XtNewString(path);
- }
-